//
//  YSGMyopiaRecordViewModel.swift
//  EyeVisionForPatients
//
//  Created by PMC on 2021/1/6.
//  Copyright © 2021 QDSG. All rights reserved.
//

import HandyJSON

struct YSGMyopiaRecordViewModel {
    var models: [YSGMyopiaRecordDetailModel]
    
    var numberOfRow: Int { models.count }
    
    func viewModel(at indexPath: IndexPath) -> YSGMyopiaRecordDetailViewModel {
        return YSGMyopiaRecordDetailViewModel(model: models[indexPath.row])
    }
    
    mutating func loadMore(with models: [YSGMyopiaRecordDetailModel]) {
        self.models += models
    }
    
    /// 获取检查单列表数据
    static func getMyopiaRecordList(current: Int, size: Int = 10, finished: @escaping ([YSGMyopiaRecordDetailModel]?, String?, HttpCode) -> Void) {
        let params: [String: Any] = ["current": current, "size": size]
        YSGLog("检查单列表 params: \(params)")
        HttpTool.shared.request(target: ApiManager.myopiaRecordList(paras: params)) { (json, code) in
            YSGLog("检查单列表 json: \(json)")
            let models = JSONDeserializer<YSGMyopiaRecordDetailModel>.deserializeModelArrayFrom(json: json["data"]["records"].description) as? [YSGMyopiaRecordDetailModel]
            finished(models, json["message"].description, code)
        } failure: { error in
            YSGLog("检查单列表 error: \(error?.debugDescription ?? "Unknown Error")")
            finished(nil, error?.description, .failure)
        }
    }
    
    /// 取消检查预约
    static func cancelMyopiaReserve(recordId: String, finished: @escaping (String?, HttpCode) -> Void) {
        let params = ["checkFormDetailId": recordId]
        YSGLog("取消检查预约 params: \(params)")
        HttpTool.shared.request(target: ApiManager.myopiaCancelReserve(paras: params)) { (json, code) in
            YSGLog("取消检查预约 json: \(json)")
            finished(json["message"].description, code)
        } failure: { error in
            YSGLog("取消检查预约 error: \(error?.debugDescription ?? "Unknown Error")")
            finished(error?.description, .failure)
        }
    }
    
    /// 获取检查单详情
    static func getMyopiaRecordDetail(recordId: String, finished: @escaping (YSGMyopiaRecordDetailModel?, String?, HttpCode) -> Void) {
        let params = ["checkDetailId": recordId]
        YSGLog("检查单详情 params: \(params)")
        HttpTool.shared.request(target: ApiManager.myopiaRecordDetail(paras: params)) { (json, code) in
            YSGLog("检查单详情 json: \(json)")
            let model = YSGMyopiaRecordDetailModel.deserialize(from: json["data"].description)
            finished(model, json["message"].description, code)
        } failure: { error in
            YSGLog("检查单详情 error: \(error?.debugDescription ?? "Unknown Error.")")
            finished(nil, error?.description, .failure)
        }
    }
    
    /// 编辑检查信息
    static func editMyopiaRecordDetail(recordId: String, checkInfo: [[String: Any]], finished: @escaping (String?, HttpCode) -> Void) {
        let params: [String: Any] = ["checkDetailId": recordId, "impression": checkInfo]
        YSGLog("编辑检查信息 params: \(params)")
        HttpTool.shared.request(target: ApiManager.myopiaRecordDetailEdit(paras: params)) { (json, code) in
            YSGLog("编辑检查信息 json: \(json)")
            finished(json["message"].description, code)
        } failure: { error in
            YSGLog("编辑检查信息 error: \(error?.debugDescription ?? "Unknown Error.")")
            finished(error?.description, .failure)
        }
    }
}

struct YSGMyopiaRecordDetailViewModel {
    var model: YSGMyopiaRecordDetailModel
    
    /// 患者姓名
    var name: NSAttributedString {
        let attriName = NSMutableAttributedString()
        let attriName1 = NSAttributedString(
            string: "姓名：",
            attributes: [
                NSAttributedString.Key.foregroundColor: UIColor.textDark,
                NSAttributedString.Key.font: UIFont.regular(14)
            ]
        )
        let attriName2 = NSAttributedString(
            string: model.patientName ?? "",
            attributes: [
                NSAttributedString.Key.foregroundColor: UIColor.textDark,
                NSAttributedString.Key.font: UIFont.medium(16)
            ]
        )
        attriName.append(attriName1)
        attriName.append(attriName2)
        return attriName
    }
    
    /// 检查单号
    var recordNumber: NSAttributedString {
        let attriNumber = NSMutableAttributedString()
        let attriNum1 = NSAttributedString(
            string: "检查单号：",
            attributes: [
                NSAttributedString.Key.foregroundColor: UIColor.textLight,
                NSAttributedString.Key.font: UIFont.regular(14)
            ]
        )
        let attriNum2 = NSAttributedString(
            string: model.applyFormId ?? "",
            attributes: [
                NSAttributedString.Key.foregroundColor: UIColor.textDark,
                NSAttributedString.Key.font: UIFont.medium(16)
            ]
        )
        attriNumber.append(attriNum1)
        attriNumber.append(attriNum2)
        return attriNumber
    }
    
    /// 检查部位
    var recordPosition: String { "检查部位：\(model.checkSeries ?? "")" }
    
    /// 预约时间
    var reserveTime: String { "预约时间：\(model.checkTime ?? "")" }
    
    /// 医院名称
    var hospitalName: String { "检查医院：\(model.hosName ?? "")" }
    
    /// 是否能取消
    var canCancel: Bool { model.cancelFlag == 1 }
    
    /// 是否已编辑
    var isEdited: Bool { model.checkFlag == 2 }
    
    var numberOfSection: Int {
        switch model.checkItemCode {
        case .eyePhoto,
             .eyePrevious: return 2
        case .eyePressure,
             .eyeVision,
             .eyeRefractive: return 3
        default: return 0
        }
    }
    
    func cellHeight(at indexPath: IndexPath) -> CGFloat {
        switch model.checkItemCode {
        case .eyePhoto,
             .eyePrevious:
            return indexPath.row == 0 ? (model.oS?.isEmpty == false ? 185 : 0) : (model.oD?.isEmpty == false ? 185 : 0)
        case .eyePressure: return 160
        case .eyeVision: return 60
        case .eyeRefractive: return 180
        default: return 0
        }
    }
    
    func numberOfRow(in section: Int) -> Int {
        switch section {
        case 0: return 1
        case 1:
            switch model.checkItemCode {
            case .eyePhoto,
                 .eyePrevious: return 2
            case .eyePressure,
                 .eyeVision,
                 .eyeRefractive: return checkInfoArr.count
            default: return 0
            }
        case 2: return 1
        default: return 0
        }
    }
    
    var checkInfoArr: [YSGMyopiaRecordDetailCheckInfo] = []
    
    mutating func setCheckInfoArr() {
        guard let models = model.impression else {
            switch model.checkItemCode {
            case .eyePressure:
                self.checkInfoArr = [
                    YSGMyopiaRecordDetailCheckInfo(title: "第1次测量"),
                    YSGMyopiaRecordDetailCheckInfo(title: "眼压测量结果（平均数值)")
                ]
            case .eyeVision:
                self.checkInfoArr = [
                    YSGMyopiaRecordDetailCheckInfo(title: "左眼视力"),
                    YSGMyopiaRecordDetailCheckInfo(title: "右眼视力")
                ]
            case .eyeRefractive:
                self.checkInfoArr = [
                    YSGMyopiaRecordDetailCheckInfo(title: "左眼"),
                    YSGMyopiaRecordDetailCheckInfo(title: "右眼")
                ]
            default:
                break
            }
            return
        }
        
        self.checkInfoArr = models
    }
    
    mutating func addCheckInfo() {
        let count = checkInfoArr.count
        let checkInfo = YSGMyopiaRecordDetailCheckInfo(title: "第\(count)次测量", isCanDelete: true)
        checkInfoArr.insert(checkInfo, at: count - 1)
    }
    
    mutating func removeCheckInfo(at indexPath: IndexPath) {
        if indexPath.row < checkInfoArr.count {
            checkInfoArr.remove(at: indexPath.row)
        }
    }
    
    mutating func replaceCheckInfo(_ checkInfo: YSGMyopiaRecordDetailCheckInfo, at indexPath: IndexPath) {
        if indexPath.row < checkInfoArr.count {
            checkInfoArr[indexPath.row] = checkInfo
        }
    }
    
    mutating func toArray() -> [[String: Any]] {
        return checkInfoArr.map { model -> [String: Any] in
            return [
                "title": model.title ?? "",
                "odEyePressure": model.odEyePressure ?? "",
                "osEyePressure": model.osEyePressure ?? "",
                "eyeVision": model.eyeVision ?? "",
                "ballDegree": model.ballDegree ?? "",
                "columnDegree": model.columnDegree ?? "",
                "axis": model.axis ?? "",
            ]
        }
    }
    
    var canSave: Bool {
        switch model.checkItemCode {
        case .eyePressure:
            if isEdited {
                return false
            } else {
                let previous = checkInfoArr[checkInfoArr.count - 2]
                let last = checkInfoArr[checkInfoArr.count - 1]
                return previous.osEyePressure?.isEmpty == false ||
                    previous.odEyePressure?.isEmpty == false ||
                    last.osEyePressure?.isEmpty == false ||
                    last.odEyePressure?.isEmpty == false
            }
        case .eyeVision:
            if isEdited {
                return false
            } else {
                guard let first = checkInfoArr.first, let last = checkInfoArr.last else { return false }
                return first.eyeVision?.isEmpty == false || last.eyeVision?.isEmpty == false
            }
        case .eyeRefractive:
            if isEdited {
                return false
            } else {
                guard let first = checkInfoArr.first, let last = checkInfoArr.last else { return false }
                return first.ballDegree?.isEmpty == false ||
                    first.columnDegree?.isEmpty == false ||
                    first.axis?.isEmpty == false ||
                    last.ballDegree?.isEmpty == false ||
                    last.columnDegree?.isEmpty == false ||
                    last.axis?.isEmpty == false
            }
        default:
            return false
        }
    }
    
    var canAdd: Bool {
        switch model.checkItemCode {
        case .eyePressure:
            if isEdited {
                return false
            } else {
                let previous = checkInfoArr[checkInfoArr.count - 2]
                return previous.odEyePressure?.isEmpty == false ||
                    previous.osEyePressure?.isEmpty == false
            }
        default:
            return false
        }
    }
    
    /// 获取患者病情描述
    func getPatientDescription() -> String {
        switch model.checkItemCode {
        case .eyePressure:
            guard let last = checkInfoArr.last else { return "" }
            return "左眼眼压\(last.osEyePressure ?? " "); 右眼眼压\(last.odEyePressure ?? " ")"
        case .eyeVision:
            guard let first = checkInfoArr.first, let last = checkInfoArr.last else { return "" }
            return "左眼视力\(first.eyeVision ?? " "); 右眼视力\(last.eyeVision ?? " ")"
        case .eyeRefractive:
            guard let first = checkInfoArr.first, let last = checkInfoArr.last else { return "" }
            return "左眼：球镜度数\(first.ballDegree ?? " "), 柱镜度数\(first.columnDegree ?? " "), 轴位\(first.axis ?? " ")" + ";" + "右眼：球镜度数\(last.ballDegree ?? " "), 柱镜度数\(last.columnDegree ?? " "), 轴位\(last.axis ?? " ")"
        default:
            return ""
        }
    }
    
    /// 获取图片model
    func getImageModels() -> [UploadImgModel] {
        var models = [UploadImgModel]()
        switch model.checkItemCode {
        case .eyePhoto, .eyePrevious:
            for i in 0..<2 {
                if i == 0 {
                    if model.oS?.isEmpty == false {
                        models.append(UploadImgModel(resourceId: "\(model.oSResourceId)", shareUrl: model.oS))
                    }
                } else {
                    if model.oD?.isEmpty == false {
                        models.append(UploadImgModel(resourceId: "\(model.oDResourceId)", shareUrl: model.oD))
                    }
                }
            }
            return models
        default:
            if model.url?.isEmpty == false {
                models.append(UploadImgModel(resourceId: "\(model.resourceId)", shareUrl: model.url))
            }
            return models
        }
    }
}
